﻿using Microsoft.CSharp;
using SeleniumExtension.Models;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SeleniumExtension.Engine
{
    public class DynamicCodeExecution
    {
        public static List<Results> AutoExecuteCode()
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            ICodeCompiler compiler = provider.CreateCompiler();
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateExecutable = false;
            parameters.GenerateInMemory = true;
            parameters.IncludeDebugInformation = false;
            parameters.TreatWarningsAsErrors = false;
            parameters.CompilerOptions = string.Format("/lib:{0}", "c:\\Selenium\bin");
            parameters.ReferencedAssemblies.Add("System.dll");
            parameters.ReferencedAssemblies.Add("System.Core.dll");
            parameters.ReferencedAssemblies.Add("WebDriver.dll");
            parameters.ReferencedAssemblies.Add("SeleniumExtension.dll");
            string dynamicCode = new SeleniumExtension.Services.MockSqlServices().GetDynamicDataObjects().FirstOrDefault().DynamicCode; //call db and get the code
            parameters.GenerateInMemory = false;
            CompilerResults compiled = provider.CompileAssemblyFromSource(parameters, dynamicCode);
            if (compiled.Errors.HasErrors)
            {
                string errorMessage = "Has an Error : \n";

                for (int i = 0; i < compiled.Errors.Count; i++)
                {
                    errorMessage = errorMessage + "\r\nLine : " + compiled.Errors[i].Line.ToString() + " - " + compiled.Errors[i].ErrorText;
                }
                throw (new Exception(errorMessage));
            }

            Assembly assembly = compiled.CompiledAssembly;
            object instanceObject = assembly.CreateInstance("SeleniumExtension.Services.MockDynaObject");
            if (instanceObject == null)
            {
                throw (new Exception("Could not create an instance of dynamic object or the object was null"));
            }

            object[] codeParams = new object[0];

            try
            {
                object objResults = instanceObject.GetType().InvokeMember("Run", BindingFlags.InvokeMethod, null, assembly, codeParams);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            if (instanceObject != null)
                return (List<Results>)instanceObject;
            return null;
        }
    }
}
